<?php


namespace App\Models\CacheModel;


use app\common\lib\exception\ApiException;
use app\common\lib\Util;
use App\Models\Api\BaseCache;
use GuzzleHttp\Exception\GuzzleException;
use think\Cache;
use think\Log;
use think\response\Json;
use AstroTool\Cache\CacheManage;

class AppQq extends BaseCache
{
    protected $table = 'wechat_backup_07_18_14_43_00.app_qq';
    protected $cacheModel = 'user.qq';
    const QQ_USERINFO_URL = 'https://graph.qq.com/user/get_user_info';
    const QQ_CLIENT_ID = '1106558601';
    const QQ_UNIONID_URL = 'https://graph.qq.com/oauth2.0/me';

    /**
     * 添加用户qq信息
     * @param $openid
     * @param $map
     * @return bool
     */
    public function SaveData($map)
    {
        $res = Cache::get($map['unionid']);
        if ($res)
        {
            throw new ApiException('当前账号已注册，请勿重复操作');
        }
        Cache::set($map['unionid'], 1, 2);
        try
        {
            $this->save($map);
        }
        catch (\Exception $e)
        {
            Log::write('添加用户qq信息失败：' . $e->getMessage(), 'error', true);
            return false;
        }
        return true;
    }

    /**
     *  更新用户qq信息
     * @param $data
     * @param $map
     * @param int $type 1=>unionid,2=>uid
     * @return bool
     * @throws \Exception
     */
    public function UpdateData($data, $map, $uid, $unionid)
    {
        try
        {
            $this->where($map)->update($data);
        }
        catch (\Exception $e)
        {
            Log::write('更新用户qq信息失败：' . $e->getMessage(), 'error', true);
            return false;
        }
        CacheManage::getInstance()->setCacheConfig($this->cacheModel, $unionid . '-1')->rmCache();
        CacheManage::getInstance()->setCacheConfig($this->cacheModel, $uid . '-2')->rmCache();
        return true;
    }

    /**
     * 删除用户qq账号
     * @param $uid
     * @return bool
     * @throws \Exception
     */
    public function DelData($uid)
    {
        $qqInfo = $this->getUserQqInfoFromCache($uid, 2);
        if ($qqInfo)
        {
            try
            {
                $this->where(['uid' => $uid])->delete();
            }
            catch (\Exception $e)
            {
                return false;
            }
            CacheManage::getInstance()->setCacheConfig($this->cacheModel, $qqInfo['unionid'] . '-1')->rmCache();
            CacheManage::getInstance()->setCacheConfig($this->cacheModel, $uid . '-2')->rmCache();
        }
        return true;
    }

    /**
     * QQ登录
     * @param $param
     * @return array|Json
     * @throws ApiException
     * @throws GuzzleException
     * @throws \Exception
     */
    public function QqInfo($param)
    {
        if (!array_key_exists('access_token', $param))
        {
            throw new ApiException('access_token 不存在 无法获取用户信息!', 200, 0);
        }
        if (!array_key_exists('openid', $param))
        {
            throw new ApiException('用户openID不存在,请重新登录!', 200, 0);
        }
        //获取用户UNIONID
        $get_user_unionid = self::QQ_UNIONID_URL . '?access_token=' . $param['access_token'] . '&unionid=1';
        $get_user_unionid = Util::curl_get($get_user_unionid);
        if (strpos($get_user_unionid, "callback") !== false)
        {
            $lpos = strpos($get_user_unionid, "(");
            $rpos = strrpos($get_user_unionid, ")");
            $response = substr($get_user_unionid, $lpos + 1, $rpos - $lpos - 1);
            $user_unionid_info = json_decode($response, true);
            if (isset($user_unionid_info['error']))
            {
                Log::write('获取qq信息失败：' . json_encode($user_unionid_info, true) . PHP_EOL . '请求参数：' . json_encode($param, true), 'error', true);
                throw new ApiException($user_unionid_info['error_description']);
            }
        } else
        {
            Log::write('获取qq信息失败：' . json_encode($get_user_unionid, true) . PHP_EOL . '请求参数：' . json_encode($param, true), 'error', true);
            $user_unionid_info['unionid'] = '';
        }
        //获取用户qq信息
        $get_user_info = self::QQ_USERINFO_URL . '?access_token=' . $param['access_token'] . '&oauth_consumer_key=' . self::QQ_CLIENT_ID . '&openid=' . $param['openid'];
        $UserResult = Util::curl_get($get_user_info);
        $qq_user = json_decode($UserResult, true);
        if ($qq_user['ret'] != 0)
        {
            throw new ApiException($qq_user['msg'], 200, 0);
        }
        switch (true)
        {
            case $qq_user['gender'] == '男'://gender 1=》男，2=》女
                $sex = 1;
                break;
            case $qq_user['gender'] == '女':
                $sex = 2;
                break;
            default :
                $sex = 0;
        }
        $qq_user['headimgurl'] = $qq_user['figureurl_qq_1'];
        $qq_user['openid'] = $param['openid'];
        $qq_user['sex'] = $sex;//gender_type 1=》男，2=》女
        $qq_user['unionid'] = $user_unionid_info['unionid'];//unionid
        if ($qq_user)
        {
            return $qq_user;
        }
        throw new ApiException('qq授权失败', 200, 0);
    }


    /**
     *  缓存获取用户qq信息
     * @param $param
     * @param int $type 1=>unionid,2=>uid
     * @return array|bool|mixed
     * @throws ApiException
     */
    public function getUserQqInfoFromCache($param, $type = 1)
    {
        $data = CacheManage::getInstance()->setCacheConfig($this->cacheModel, $param . '-' . $type)->getDataAndSet(function () use ($type, $param)
        {
            return $this->getUserQqInfoFromDb($param, $type);
        }, ['uid', 'uen', 'nickname', 'avatar', 'forbidden', 'email', 'is_first_login', 'uc_id', 'sex', 'has_self_recode', 'unionid']);

        if ($data && $data['forbidden'] == 1)
        {
            throw new ApiException('该账号禁止登录', 200, 0);
        }
        return $data;
    }

    /**
     * 数据库获取用户qq信息
     * @param int $type 1=>unionid,2=>uid
     * @param $param
     * @return array
     */
    public function getUserQqInfoFromDb($param, $type = 1)
    {
        switch ($type)
        {
            case 1:
                $where = ['q.unionid' => $param];
                break;
            case 2:
                $where = ['q.uid' => $param];
                break;
            default:
                return [];
                break;
        }
        try
        {
            $data = $this
                ->alias('q')
                ->field('u.id uid,u.uen,q.nickname,u.avatar,u.forbidden,u.email,u.is_first_login,u.uc_id,u.sex,u.has_self_recode,q.unionid')
                ->join('wechat_backup_07_18_14_43_00.app_user u', 'q.uid=u.id')
                ->where($where)
                ->findOrFail()->toArray();
        }
        catch (\Exception $e)
        {
            $data = [];
        }
        return $data;
    }
}
